home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 40
/
Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso
/
Aminet
/
misc
/
emu
/
ATUtilities.lha
/
ATUtilities
/
Printer.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-09-26
|
13KB
|
597 lines
/* ******************************************************************* */
/* ** ** */
/* ** ATKeyboard Version 4.0 ** */
/* ** Copright (C) 1992-1994 by Thomas Dreibholz ** */
/* ** All rights reserved ** */
/* ** ** */
/* ** LPT1-Verwaltung ** */
/* ** ** */
/* ******************************************************************* */
#include "janus.h"
#include "ATKeyboard.h"
extern struct Einstellungen Einstellungen;
extern struct Window *WindowPtr;
extern struct MsgPort *Port3,*Port5,*Message1;
extern struct Menu Menu1;
extern struct MenuItem LPT1_Item,Kontrollfenster_Item;
extern struct JanusBase *JanusBase;
extern struct IOExtPar *ParallelRequest;
extern struct TextFont *OpalFont;
EXTERN BOOL LPT1;
struct LPT1Data
{
UBYTE *JanusData;
UBYTE *Buffer;
ULONG BufferPos;
ULONG MaxPos;
UBYTE Control;
UBYTE LED;
UBYTE *PublicBuffer;
struct SetupSig ParallelInt;
};
BOOL CheckOutput();
BOOL OpenOutput();
VOID CloseOutput();
VOID PrinterTask();
UBYTE *PrinterTaskName="ATKeyboard Printer Task by Thomas Dreibholz";
ULONG transfer=0L;
UBYTE Papier=1;
UBYTE Drucker=1;
UBYTE Cache=1;
UBYTE Umlenkung;
UWORD cp1=0,cp2=0;
LONG ParallelDev=-1L;
struct LPT1Data data;
struct Window *KWindow;
struct RastPort *KRastPort;
struct Task *LPT1Task;
struct SetupSig *ParallelInt;
struct FileHandle *LPTOutput;
#define xMENUENABLED (0xffff-MENUENABLED)
UBYTE *DruckerStat[]={"Offline ",
"Online "};
UBYTE *PapierStat[]={"Kein Papier ",
"Papier okay "};
UBYTE *CacheStat[]={"Datenstau! ",
"%ld.%02ld%% voll "};
/* Text an (x,y) ausgeben */
VOID GfxText(rp,x,y,tex)
struct RastPort *rp;
UWORD x,y;
UBYTE *tex;
{
Move(rp,x,y);
Text(rp,tex,strlen(tex));
}
/* Cache-Belegung in Prozent */
VOID CacheCalc(size)
ULONG size;
{
UBYTE buffer[25];
REGISTER UWORD i;
if(KRastPort!=NULL)
{
i=(UWORD)((size*10000)/(data.MaxPos-4));
cp1=(UWORD)(i / 100);
cp2=(UWORD)(i % 100);
sprintf(&buffer,CacheStat[Cache],cp1,cp2);
GfxText(KRastPort,325,10,&buffer);
}
}
/* Kontrollfenster-Ausgabe */
VOID KAusgabe(num)
UBYTE num;
{
UBYTE buffer[30];
if(KRastPort!=NULL)
{
if(num & 1)
{
sprintf(&buffer,"%ld Bytes ",transfer);
GfxText(KRastPort,95,10,&buffer);
}
if(num & 2)
{
GfxText(KRastPort,95,20,PapierStat[Papier]);
GfxText(KRastPort,325,20,DruckerStat[Drucker]);
}
}
}
/* Kontrollfenster-Verwaltung */
VOID Kontrollfenster(ende)
BOOL ende;
{
if(ende==FALSE)
{
if(Kontrollfenster_Item.Flags & CHECKED)
{
if(KWindow==NULL)
{
KWindow=CreateStdWindow("ATKeyboard - LPT1 Kontrollfenster",
75,20,450,28+BorderHeight(),
0L,WINDOWDEPTH|WINDOWDRAG|GIMMEZEROZERO);
if(KWindow!=NULL)
{
KRastPort=KWindow->RPort;
SetFont(KRastPort,OpalFont);
SetAPen(KRastPort,1);
GfxText(KRastPort,10,10,"Transfer:");
GfxText(KRastPort,250,10,"Cache:");
GfxText(KRastPort,10,20,"Papier:");
GfxText(KRastPort,250,20,"Drucker:");
KAusgabe(3);
}
}
}
else
{
if(KWindow!=NULL)
{
KRastPort=NULL;
DeleteStdWindow(KWindow);
KWindow=NULL;
}
}
ClearMenuStrip(WindowPtr);
if(KWindow==NULL) Inaktiv(&Kontrollfenster_Item); else Aktiv(&Kontrollfenster_Item);
SetMenuStrip(WindowPtr,&Menu1);
}
else
{
if(KWindow!=NULL)
{
KRastPort=NULL;
DeleteStdWindow(KWindow);
KWindow=NULL;
}
}
}
/* LPT1 starten oder beenden */
VOID KontrolliereLPT1()
{
REGISTER LONG i;
REGISTER BOOL bool;
if(LPT1==TRUE)
{
if(LPT1Task==NULL)
{
i=JanusBase->JIntTable->JanusInts[JSERV_LPT1INT];
if(i<=NULL)
{
bool=OpenOutput();
if(bool==TRUE)
{
ParallelInt=&data.ParallelInt;
LPT1Task=CreateProcess(PrinterTask,2500,PrinterTaskName,0);
if(LPT1Task!=NULL)
{
data.Buffer=AllocMem(Einstellungen.Puffergroesse*2,MEMF_PUBLIC);
if(data.Buffer!=NULL)
{
data.PublicBuffer=(ULONG)data.Buffer+(ULONG)Einstellungen.Puffergroesse;
data.BufferPos=0;
data.MaxPos=Einstellungen.Puffergroesse;
data.JanusData=JanusBase->IOAccessRAM;
InstallLPT1Int(ParallelInt);
ParallelInt->ss_Interrupt.is_Data=&data;
SetJanusHandler(JSERV_LPT1INT,ParallelInt);
SetJanusEnable(5,0);
SetJanusRequest(5,1);
SetLPT1Bits();
switch(Einstellungen.Umlenkung)
{
case 0:
Say("the l p t 1 emulation is turned on, the output will be transferred to the parallel port");
break;
case 1:
Say("the l p t 1 emulation is turned on, the output will be transferred to the printer driver chosen by preferences");
break;
case 2:
Say("the l p t 1 emulation is turned on, the output will be transferred to a file");
break;
}
}
else
{
PutMsg(Port5,Message1);
WaitPort(Port3);
GetMsg(Port3);
AbortLPT1();
LPT1=FALSE;
LPT1Task=NULL;
}
}
}
else
{
Say("i am unable to open l p t 1 output file");
Requester("Die LPT1-Ausgabedatei konnte","nicht eröffnet werden.","Okay",NULL);
}
}
else
{
LPT1=FALSE;
Say("the l p t 1 interrupt is already used");
Requester("Der LPT1-Interrupt ist bereits","belegt.","Okay",NULL);
}
}
}
else
{
if(LPT1Task!=NULL)
{
PutMsg(Port5,Message1);
WaitPort(Port3);
GetMsg(Port3);
SetJanusHandler(JSERV_LPT1INT,NULL);
FreeMem(data.Buffer,data.MaxPos*2);
CloseOutput();
Say("the l p t 1 emulation is turned off");
LPT1Task=NULL;
LPT1=FALSE;
}
}
ClearMenuStrip(WindowPtr);
if(LPT1==FALSE)
{
Inaktiv(&LPT1_Item);
}
else
{
Aktiv(&LPT1_Item);
}
SetMenuStrip(WindowPtr,&Menu1);
}
/* LPT1-Reset */
VOID Druckerreset()
{
if(LPT1==TRUE)
{
Say("resetting l p t 1 emulation");
LPT1=FALSE;
KontrolliereLPT1();
Papier=Cache=Drucker=1;
transfer=0;
cp1=cp2=0;
LPT1=TRUE;
KontrolliereLPT1();
}
}
/* Druckerstatus ermitteln */
#asm
public _PrinterStat
_PrinterStat:
moveq.l #0,d0
move.b $bfd000,d0
ext.w d0
ext.l d0
rts
#endasm
/* Druckerstatus prüfen */
BOOL CheckOutput()
{
REGISTER BOOL res;
REGISTER LONG Status;
if(Umlenkung==2)
{
Drucker=Papier=1;
res=TRUE;
}
else
{
Status=PrinterStat();
if(Status & (1<<0)) Drucker=0; else Drucker=1;
if(Status & (1<<1)) Papier=0; else Papier=1;
if(((CheckIO(ParallelRequest))!=NULL)) res=TRUE; else res=FALSE;
}
return(res);
}
/* Datenausgabe öffnen */
BOOL OpenOutput()
{
REGISTER BOOL res;
res=TRUE;
if(Einstellungen.Umlenkung==2)
{
Umlenkung=2;
LPTOutput=Open(&Einstellungen.LPT1Name,MODE_NEWFILE);
if(LPTOutput==NULL) res=FALSE;
}
else
{
Umlenkung=Einstellungen.Umlenkung;
if(Umlenkung==0)
{
ParallelDev=OpenDevice("parallel.device",0,ParallelRequest,0);
}
else
{
ParallelDev=OpenDevice("printer.device",0,ParallelRequest,0);
}
if(ParallelDev!=0) res=FALSE;
}
if(Einstellungen.LED) data.LED=0x7F; else data.LED=0x00;
return(res);
}
/* Datenausgabe schließen */
VOID CloseOutput()
{
if(LPTOutput)
{
Close(LPTOutput);
LPTOutput=NULL;
}
else if(ParallelDev==0)
{
AbortIO(ParallelRequest);
CloseDevice(ParallelRequest);
ParallelRequest->io_Device=NULL;
ParallelRequest->io_Unit=NULL;
ParallelDev=-1L;
}
if(data.LED) OffLED();
}
/* LPT1-Manager-Task */
VOID PrinterTask()
{
REGISTER WORD time;
REGISTER BOOL writeIt,bool;
REGISTER ULONG size;
register struct Message *msg;
geta4();
msg=NULL;
Papier=1;
Drucker=1;
Cache=1;
transfer=0;
Kontrollfenster(FALSE);
do
{
writeIt=FALSE;
bool=CheckOutput();
if(bool==TRUE)
{
Disable();
size=data.BufferPos;
if(size>0)
{
CopyMem(data.Buffer,data.PublicBuffer,size);
data.BufferPos=0;
writeIt=TRUE;
Enable();
ReadyLPT1(&data);
} else Enable();
if(size>=(data.MaxPos-4)) Cache=0; else Cache=1;
CacheCalc(size);
if(writeIt)
{
transfer+=size;
if(LPTOutput)
{
Write(LPTOutput,data.PublicBuffer,size);
}
else
{
ParallelRequest->IOPar.io_Data=data.PublicBuffer;
ParallelRequest->IOPar.io_Length=size;
ParallelRequest->IOPar.io_Command=CMD_WRITE;
SendIO(ParallelRequest);
}
KAusgabe(3);
}
else
{
KAusgabe(2);
}
}
else
{
if(KRastPort!=NULL)
{
Disable();
size=data.BufferPos;
Enable();
if(size>=(data.MaxPos-4)) Cache=0; else Cache=1;
CacheCalc(size);
transfer+=size;
KAusgabe(3);
transfer-=size;
}
}
time=Einstellungen.Leerungszeit;
do
{
Delay(5);
time-=5;
msg=GetMsg(Port5);
} while((time>0)&&(msg==NULL));
}
while(msg==NULL);
Kontrollfenster(TRUE);
ReplyMsg(msg);
}
#asm
* LPT1 aktivieren
public _JanusBase
public _SetLPT1Bits
_SetLPT1Bits:
move.l a6,-(sp)
move.l _JanusBase,a6
move.l 46(a6),a6
move.b #88,447(a6)
bclr #4,8189(a6)
move.l (sp)+,a6
rts
* LPT1 ist wieder zur Datenübertragung bereit
public _ReadyLPT1
_ReadyLPT1:
movem.l a1/a6,-(sp)
move.l 12(sp),a1
jsr Disable
move.l _JanusBase,a6
move.l 46(a6),a6
tst.b 16(a1)
beq ReadyLPT1_Okay
; -----------------------------------------------------------
tst.b 17(a1)
beq KeineWarnung
bchg #1,$bfe001
KeineWarnung:
clr.b 16(a1)
move.b #88,447(a6)
bclr #4,8189(a6)
btst #4,479(a6)
beq.s ReadyLPT1_Okay
move.b #-10,8187(a6)
bra ReadyLPT1_Okay
; -----------------------------------------------------------
ReadyLPT1_Okay:
jsr Enable
movem.l (sp)+,a1/a6
rts
* Drucker ist nicht bereit
public _AbortLPT1
_AbortLPT1:
move.l a6,-(sp)
move.l _JanusBase,a6
move.l 46(a6),a6
bset #4,447(a6)
bset #5,447(a6)
move.l (sp)+,a6
rts
* Installieren des is_Code-Vektors
public _InstallLPT1Int
_InstallLPT1Int:
move.l a6,-(sp)
move.l 8(sp),a6
move.l #Handler,18(a6)
move.l (sp)+,a6
rts
* LPT1-Datentransfer Interrupt-Handler
Handler:
jsr Disable
movem.l d0-d2/a0-a3,-(sp)
move.l a1,a3 ; A3=HandlerIO
move.l 0(a3),a1 ; A1=IOAccessRAM
move.l 4(a3),a2 ; A2=Memory
move.l 8(a3),d1 ; D1=Position
move.l 12(a3),d2 ; D2=MaxPos
; -----------------------------------------------------------
subq.l #4,d2
cmp.l d2,d1 ; Vergl. Position und MaxPos-1
blo PosOkay ; Kleiner -> PosOkay
beq PosWarn ; Gleich -> PosWarn
; Größer -> PosError
; --- Cache ist voll ----------------------------------------
PosError:
bset #4,447(a1) ; LPT1-Bit: Drucker nicht bereit
bra Weiter ; Ende
; --- Cache hat nur noch 1 freies Byte ----------------------
PosWarn:
move.b 415(a1),0(a2,d1.l) ; Byte sichern
bset #4,447(a1) ; LPT1-Bit: Drucker nicht bereit
addq.l #1,8(a3) ; Pos-Zähler erhöhen
move.b #$7F,16(a3) ; Cache-Control
bra Weiter
; --- Cache hat genug freie Bytes ---------------------------
PosOkay:
move.b 415(a1),0(a2,d1.l) ; Byte sichern
move.b #88,447(a1) ; LPT1-Bits: Alles okay
addq.l #1,8(a3) ; Pos-Zähler erhöhen
; -----------------------------------------------------------
Reply:
bclr #4,8189(a1)
btst #4,479(a1)
beq.s Weiter
move.b #-10,8187(a1)
Weiter:
movem.l (sp)+,d0-d2/a0-a3
jsr Enable
rts
* Interrupts sperren
Disable:
movem.l d0-d7/a0-a6,-(sp)
move.l $4,a6
jsr -120(a6)
movem.l (sp)+,d0-d7/a0-a6
rts
* Interrupts erlauben
Enable:
movem.l d0-d7/a0-a6,-(sp)
move.l $4,a6
jsr -126(a6)
movem.l (sp)+,d0-d7/a0-a6
rts
* LED ausschalten
public _OffLED
_OffLED:
bclr #1,$bfe001
rts
#endasm